import org.json.JSONObject;

import javax.swing.*;
import javax.swing.table.AbstractTableModel;
import javax.swing.table.DefaultTableModel;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.FocusEvent;
import java.awt.event.FocusListener;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.ServerSocket;
import java.net.Socket;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Vector;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

public class Frame extends JFrame {

    //数据中转类
    private static class Transfer {
       public static DefaultTableModel model;
    }

    private ArrayList usetList = new ArrayList<>();


    private Vector tableTitle = new Vector();
    private Vector<Vector> tableData = new Vector<>();


    //表格操作
    private class TableModel extends AbstractTableModel {

        @Override
        public int getRowCount() {
            return tableData.size();
        }

        @Override
        public int getColumnCount() {
            return tableTitle.size();
        }

        @Override
        public Object getValueAt(int rowIndex, int columnIndex) {
            return tableData.get(rowIndex).get(columnIndex);
        }

        @Override
        public String getColumnName(int column) {
            return (String) tableTitle.get(column);
        }

        @Override
        public boolean isCellEditable(int rowIndex, int columnIndex) {
            return false;
        }
    }

    //客户端集合
    ArrayList<ClientThread> clients = new ArrayList<>();
    //监听客户
    private class Accept implements Runnable {
        @Override
        public void run() {
            while (true) {
                try {
                    socket = server.accept();
                    ClientThread clientThread = new ClientThread();
                    es.submit(clientThread);
                    clients.add(clientThread);
                    System.out.println(clientThread);
                } catch (IOException e) {

                }
            }
        }
    }




    //表格
    JTable tableAirport;
    JScrollPane jScrollPane = new JScrollPane();

    JFileChooser jfc = new JFileChooser(new File("."));
    JButton btnOpen = new JButton("选择文件");
    JButton btnSend = new JButton("发送");
    JLabel feedback = new JLabel();
    JTextField txtFilePath = new JTextField("文件路径");
    JTextField txtVersion = new JTextField("版本信息");

    //创建服务器
    ServerSocket server = new ServerSocket(5050);
    Socket socket;

    //文件操作
    FileInfo file;
    String filePath;//文件路径
    boolean sending = false;//是否正在发送

    //创建线程池
    ExecutorService es = Executors.newFixedThreadPool(100);


    public Frame(String title) throws IOException {
        super(title);
        Container container = getContentPane();
        container.setLayout(new BorderLayout());



        //头部
        Panel head = new Panel(new GridLayout(2,1));
        Panel panButton = new Panel(new GridLayout(1,1));
        Panel panTxt = new Panel(new BorderLayout(2,0));
        panButton.add(btnOpen);
        panButton.add(btnSend);
        head.add(panButton);
        panTxt.add(txtFilePath,BorderLayout.CENTER);
        panTxt.add(txtVersion,BorderLayout.EAST);
        head.add(panTxt);
        container.add(head,BorderLayout.NORTH);
        tableTitle.add("机场");
        tableTitle.add("ip地址");
        tableTitle.add("状态");
        //中间
        Transfer.model = new DefaultTableModel(tableData,tableTitle);
        tableAirport = new JTable(Transfer.model);
        container.add(new JScrollPane(tableAirport),BorderLayout.CENTER);
        //底部
        container.add(feedback,BorderLayout.SOUTH);

        //服务器监听
        feedback.setText("当前在线机场数：0");
        //es.submit(new Accept());
        es.submit(new Accept());



        //文件路径焦点事件
        txtFilePath.addFocusListener(new FocusListener() {
            @Override
            public void focusGained(FocusEvent focusEvent) {
                //输入框得到焦点
                if (txtFilePath.getText().equals("文件路径")) {
                    txtFilePath.setText("");
                }
            }

            @Override
            public void focusLost(FocusEvent focusEvent) {
                //输入框失去焦点时
                if (txtFilePath.getText().equals("")) {
                    txtFilePath.setText("文件路径");
                }
            }
        });

        //版本信息焦点事件
        txtVersion.addFocusListener(new FocusListener() {
            @Override
            public void focusGained(FocusEvent focusEvent) {
                //输入框得到焦点
                if (txtVersion.getText().equals("版本信息")) {
                    txtVersion.setText("");
                }
            }

            @Override
            public void focusLost(FocusEvent focusEvent) {
                //输入框失去焦点时
                if (txtVersion.getText().equals("")) {
                    txtVersion.setText("版本信息");
                }
            }
        });

        //按钮选择文件
        btnOpen.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                btnOpen = (JButton)e.getSource();
                jfc.showOpenDialog(btnOpen);
                txtFilePath.setText(jfc.getSelectedFile().getPath());
//                String[] arr = txtFilePath.getText().split("\\\\|\\.");
//                String fileName = arr[];
            }
        });

        //按钮发送文件
        btnSend.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent actionEvent) {
                if (txtFilePath.getText().equals("文件路径")) {
                    JOptionPane.showMessageDialog(null, "请选择文件");
                    return;
                } else if (txtVersion.getText().equals("版本信息")) {
                    JOptionPane.showMessageDialog(null, "请完善版本信息");
                    return;
                }
                try {
                    for (int i = 0; i < clients.size(); i++) {
                        clients.get(i).sendFile();
                    }
                } catch (IOException e) {
                    System.out.println(e);
                }


            }
        });


    }



    //应答机制
    private void response(Airport airport) throws IOException {
        InputStream inputStream = socket.getInputStream();
        byte[] inputData = new byte[1024];
        String inputMsg = new String(inputData,0,inputStream.read(inputData),"UTF-8");
        JSONObject jsonObject = new JSONObject(inputMsg);
        String cmd = jsonObject.getString("cmd").trim();
        switch (cmd) {
            case "updateSucceed" : {
                System.out.println(airport.name + "更新成功");
                break;
            }
        }

    }

    //表格添加接入机场信息
    private void tableAdd(Airport airport) throws IOException {
        Transfer.model.addRow(new Object[] {airport.name,airport.IPAddress,"在线"});
        feedback.setText("当前在线机场数：" + Transfer.model.getRowCount());
    }


    private class ClientThread implements Runnable {
        boolean isRun = false;//区分第一次连接通信
        Airport airport;
        //第一次连接通信
        public ClientThread() throws IOException {
            try {
                InputStream inputStream = socket.getInputStream();
                byte[] inputData = new byte[1024];
                String inputMsg = new String(inputData,0,inputStream.read(inputData),"UTF-8");
                JSONObject jsonObject = new JSONObject(inputMsg);
                String cmd = jsonObject.getString("cmd").trim();
                switch (cmd) {
                    case "addAirport" : {
                        isRun = true;
                        airport = new Airport(jsonObject.optString("name"),jsonObject.getString("IPAddress"));
                        tableAdd(airport);
                        OutputStream outputStream = socket.getOutputStream();
                        jsonObject = new JSONObject();
                        jsonObject.put("cmd","addSucceed");
                        outputStream.write(jsonObject.toString(2).getBytes());
                        break;
                    }
                }
            } catch (IOException e) {
                System.out.println(e);
            }
        }

        @Override
        public void run() {
            //如果不是第一次连接，则接循环收消息
            while (isRun) {
                try {
                    response(airport);
                } catch (IOException e){
                    System.out.println(e);
                }
            }
        }

        //向全体客户端发送文件
        private void sendFile() throws IOException {
            String[] arr = txtFilePath.getText().split("\\\\|\\.");
            String fileName = arr[arr.length - 2];
            SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");//设置日期格式
            file = new FileInfo(fileName,txtVersion.getText(),df.format(new Date()));
            JSONObject jsonObject = new JSONObject(file);
            jsonObject.put("cmd","update");
            OutputStream outputStream = socket.getOutputStream();
            System.out.println(jsonObject.toString(2));
            outputStream.write(jsonObject.toString(2).getBytes());
        }

    }

}
